Skip to content

Add pull_request_target workflows for community PRs - #1386

Merged
AmyLGalles merged 9 commits into
mainfrom
add-pull-request-target-workflows
Aug 18, 2026
Merged

Add pull_request_target workflows for community PRs#1386
AmyLGalles merged 9 commits into
mainfrom
add-pull-request-target-workflows

Conversation

@AmyLGalles

@AmyLGalles AmyLGalles commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds companion -target.yml workflows to support community PRs that need secrets access, following the established pattern from bitwarden/clients.

Problem

Community PRs from forks fail when workflows require secrets (Azure auth, GitHub App tokens, etc.) because fork PRs don't have access to repository or organization secrets when triggered via pull_request events.

Current failures on community PRs:

  • Build @bitwarden/sdk-internal - breaking change detection needs secrets
  • Build Android - needs secrets for artifact publishing
  • Enforce PR labels - needs write permissions

How it works

These workflows:
Checks that the user has write permissions withcheck-run.yml, only runs on external forks, calls the existing workflows with secrets: inherit, requires manual approval - they show as action_required and must be re-run by a maintainer after code review

Related:

This follows the exact same pattern used in bitwarden/clients:

Comment thread .github/workflows/build-android-target.yml
Comment thread .github/workflows/build-wasm-internal-target.yml Outdated
Comment thread .github/workflows/enforce-labels-target.yml Outdated
Adds companion -target.yml workflows to support community PRs that need
secrets access, following the established pattern from bitwarden/clients.

Problem:
Community PRs from forks fail when workflows require secrets (Azure auth,
GitHub App tokens, etc.) because fork PRs don't have access to repository
or organization secrets when triggered via pull_request events.

Solution:
Created three new -target.yml workflows that use pull_request_target:
- build-wasm-internal-target.yml
- build-android-target.yml
- enforce-labels-target.yml

These workflows:
1. Use check-run.yml to validate the triggering actor has write permissions
2. Only run for external forks (not internal PRs)
3. Call the existing workflows with secrets: inherit
4. Require manual approval - they show as "action_required" and must be
   re-run by a maintainer after code review

Security safeguards:
- No direct checkout of PR code (calls reusable workflows)
- Fork detection: github.event.pull_request.head.repo.full_name != github.repository
- Permission validation via check-run.yml
- Manual maintainer approval required before execution

Workflow for maintainers:
1. Community PR is opened
2. Workflows fail with "action_required" status
3. Maintainer reviews PR code for safety
4. Maintainer clicks "Re-run jobs" on failed checks
5. Workflows run with secrets access after permission validation

This follows the same pattern used in bitwarden/clients for
build-cli-target.yml, build-browser-target.yml, etc.
@AmyLGalles
AmyLGalles force-pushed the add-pull-request-target-workflows branch from 98f9c06 to 2c7c2f9 Compare August 14, 2026 14:55
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

🔍 SDK Breaking Change Detection

SDK Version: add-pull-request-target-workflows (98f9c06)

⚠️ If breaking changes are detected, a corresponding pull request addressing them must be ready for merge in the affected client repository.

Client Status Details
typescript ✅ No breaking changes detected Compilation passed with new SDK version - View Details
android ❌ Breaking changes detected Compilation failed with new SDK version. A corresponding pull request addressing the breaking changes must be ready for merge in bitwarden/android. - View Details

Breaking change detection uses the build of the SDK from this branch, including any incompatibities pre-existing on or merged into this branch. Check the workflow logs to confirm.
Results update as workflows complete.

- Add workflow_call trigger to build-android.yml and build-wasm-internal.yml to make them reusable workflows
- Remove rc and hotfix-rc branch targets from build-wasm-internal-target.yml per linter requirement that pull_request_target can only target main branch
@AmyLGalles
AmyLGalles force-pushed the add-pull-request-target-workflows branch from 1cbd12e to 8626e44 Compare August 14, 2026 15:29
@AmyLGalles AmyLGalles added bug Something isn't working breaking-change labels Aug 14, 2026
@AmyLGalles
AmyLGalles marked this pull request as ready for review August 14, 2026 15:37
@AmyLGalles
AmyLGalles requested a review from a team as a code owner August 14, 2026 15:37
@AmyLGalles
AmyLGalles requested a review from coroiu August 14, 2026 15:37
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: REQUEST CHANGES

Reviewed three new pull_request_target companion workflows and the workflow_call triggers added to build-android.yml and build-wasm-internal.yml. The check-run gate plus the fork-only if condition on run-workflow follow the bitwarden/clients pattern and keep the privilege-escalation surface contained. The main concerns are downstream: the called workflows branch on github.event_name == 'pull_request' and on github.ref, and a reusable workflow inherits the caller's event context, so several jobs behave differently than intended when invoked from pull_request_target.

Code Review Details
  • ❌ : trigger-wasm-publish (if: github.ref == 'refs/heads/main') will run on every community fork PR, triggering the publish-sdk-internal-npm deployment task
    • .github/workflows/build-wasm-internal.yml:149
  • ❌ : combine job has no checkout under pull_request_target (both checkout steps are event-gated), so Move artifacts fails on a missing directory
    • .github/workflows/build-android.yml:90
  • ⚠️ : Breaking-change detection and PR version-setting are skipped under pull_request_target, and the default checkout builds the base branch instead of the PR head
    • .github/workflows/build-wasm-internal-target.yml:30
  • ⚠️ : Base workflows still run via pull_request on fork PRs and will still fail for lack of secrets/packages: write, so the originally failing checks remain red
    • .github/workflows/build-android.yml:14

Comment thread .github/workflows/build-wasm-internal.yml
Comment thread .github/workflows/build-wasm-internal-target.yml
Comment thread .github/workflows/build-android-target.yml
Comment thread .github/workflows/build-android.yml
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.41%. Comparing base (b15ab94) to head (495e731).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1386   +/-   ##
=======================================
  Coverage   86.41%   86.41%           
=======================================
  Files         501      501           
  Lines       74235    74235           
=======================================
  Hits        64149    64149           
  Misses      10086    10086           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Problem 1: trigger-wasm-publish was firing on all fork PRs
- Added event_name check to ensure it only runs on push events
- Changed condition from `github.ref == 'refs/heads/main'` to
  `github.event_name == 'push' && github.ref == 'refs/heads/main'`
- This prevents the production npm publish from triggering on every
  community fork PR

Problem 2: combine job had no checkout under pull_request_target
- Updated PR checkout step to accept both pull_request and
  pull_request_target events
- Changed ref from head.ref to head.sha for more reliable checkout
- Added repository parameter to support fork PRs
- This ensures the combine job can actually run when called from
  build-android-target.yml
@AmyLGalles
AmyLGalles force-pushed the add-pull-request-target-workflows branch from 9ad22a1 to fb25ff8 Compare August 14, 2026 17:01
The pull_request trigger still runs on fork PRs, but fork PRs don't
have access to secrets or write permissions. This causes the following
jobs to fail:

In build-android.yml:
- combine: needs packages:write for gradle publish
- check-android-breaking-changes: needs AZURE_* secrets

In build-wasm-internal.yml:
- trigger-breaking-change-check: needs AZURE_* secrets

Added fork detection to skip these jobs for external PRs:
  if: github.event_name != 'pull_request' ||
      github.event.pull_request.head.repo.full_name == github.repository

This ensures:
- Internal PRs run all checks normally via pull_request
- Fork PRs skip secrets-dependent jobs in pull_request run
- Fork PRs get secrets-dependent jobs via pull_request_target after
  maintainer approval
When called from pull_request_target workflows, the reusable workflow
inherits the caller's event context, causing several issues:

1. Checkout had no ref parameter, checked out base branch instead of PR
2. Version setting only ran for pull_request, leaving vars unset
3. Breaking-change check only ran for pull_request, was skipped
4. Integration tests checkout also had no ref parameter

Changes:
- Split checkout into PR and Push/Dispatch variants like build-android
- PR checkout uses head.sha and repository for fork support
- Updated version setting to accept pull_request_target
- Updated breaking-change check to run for:
  - Internal PRs via pull_request (has secrets)
  - Fork PRs via pull_request_target (has secrets after approval)
  - Skip for fork PRs via pull_request (no secrets)
- Fixed integration-tests checkout the same way

This ensures fork PRs build the actual PR code and run breaking-change
detection after maintainer approval.

@coroiu coroiu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just one question

Comment thread .github/workflows/enforce-labels-target.yml Outdated
The base enforce-labels.yml workflow only needs read permissions
(contents: read, pull-requests: read) and doesn't require any secrets.
Fork PRs can already run it successfully under the pull_request trigger.

The -target version added unnecessary security risk by running with
pull_request_target privileges for a workflow that only performs
read operations.

@coroiu coroiu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@AmyLGalles
AmyLGalles enabled auto-merge (squash) August 18, 2026 14:12
@AmyLGalles
AmyLGalles merged commit cc7daf1 into main Aug 18, 2026
68 checks passed
@AmyLGalles
AmyLGalles deleted the add-pull-request-target-workflows branch August 18, 2026 14:28
bw-ghapp Bot added a commit to bitwarden/sdk-swift that referenced this pull request Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants